import React, { memo, useCallback, useEffect, useRef, useState } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux';

import { getSongDetailAction,
        changeSequenceAction, 
        changeCurrentIndexAndSongAction,
        changeCurrentLyricIndexAction
} from '../store/actionCreators'
import { getSizeImage, formatDate, getPlaySong } from 'utils/format-utils'

import { Slider, message } from 'antd'
import { NavLink } from 'react-router-dom';
import {
    PlaybarWrapper,
    Control,
    PlayInfo,
    Operator
} from './style';


export default memo(function LJAppPlayerBar() {
    // props and state
    const [currentTime, setCurrentTime] = useState(0)
    const [progess, setProgess] = useState(0)
    const [isChanging, setIsChanging] = useState(false)
    const [isPlaying, setIsPlaying] = useState(false)

    // redux hooks
    const dispatch = useDispatch()
    const { currentSong, 
            sequence, 
            playList, 
            lyricList, 
            currentLyricIndex 
        } = useSelector(state => ({
        currentSong: state.getIn(["player","currentSong"]),
        sequence: state.getIn(["player", "sequence"]),
        playList: state.getIn(["player", "playList"]),
        lyricList: state.getIn(["player", "lyricList"]),
        currentLyricIndex: state.getIn(["player", "currentLyricIndex"])
    }), shallowEqual)

    // ohter hooks
    const audioRef = useRef() 
    useEffect(() => {
        dispatch(getSongDetailAction(167876))
    }, [dispatch])
    useEffect(() => {
        audioRef.current.src = getPlaySong(currentSong.id)
        audioRef.current.play().then((res) => {
            setIsPlaying(true)
        }).catch((err) => {
            setIsPlaying(false)
        })
    }, [currentSong])

    // other handle
    const picUrl = (currentSong.al && currentSong.al.picUrl) || ""
    const singerName = (currentSong.ar && currentSong.ar[0].name) || "未知歌手"
    const duration = currentSong.dt || 0
    const showDuration = formatDate(duration, "mm:ss")
    const showCurrentTime = formatDate(currentTime, "mm:ss")

    // handle function
    const playMusic = useCallback(() => {
        isPlaying? audioRef.current.pause(): audioRef.current.play()
        setIsPlaying(!isPlaying)
    }, [isPlaying])

    const timeUpdate = (e) => {
        const currentTime = e.target.currentTime
        if (!isChanging) {
            setCurrentTime(currentTime * 1000)
            setProgess(currentTime * 1000 / duration * 100)
        }

        // 获取当前歌词
        let index = 0
        for (let i=0; i<lyricList.length; i++){
            let lyricItem = lyricList[i]
            if(lyricItem.time > currentTime * 1000){
                index = i - 1
                break
            }
        }
        // console.log();
        if (currentLyricIndex !== index) {
            dispatch(changeCurrentLyricIndexAction(index))
            let content = lyricList[index] && lyricList[index].content
            message.open({
                key: "lyric",
                content: content,
                duration: 0,
                className: "lyric-class"
            })
        }
    }

    // 滑动条拖动时发生的回调
    const slideChange = useCallback((value) => {
        setIsChanging(true)

        // 随着拖动，当前时间发生更改
        const currentTime = value / 100 * duration / 1000
        setCurrentTime(currentTime * 1000)
        setProgess(value)
    }, [duration])

    // 滑动条结束拖动时发生的回调
    const slideAfterChange = useCallback((value) => {
        const currentTime = value / 100 * duration / 1000
        audioRef.current.currentTime = currentTime
        setCurrentTime(currentTime * 1000)
        setIsChanging(false)

        if(!isPlaying){
            playMusic()
        }
    }, [duration, isPlaying, playMusic])

    const changeSequence = () => {
        let currentSequence = sequence + 1
        if(currentSequence > 2){
            currentSequence = 0
        }
        dispatch(changeSequenceAction(currentSequence))
    }

    const changeMusic = (tag) => {
        dispatch(changeCurrentIndexAndSongAction(tag))
    }

    const handleMusicEnded = () => {
        if(sequence === 2){ //单曲循环
            audioRef.current.current = 0
            audioRef.current.play()
        }else{
            dispatch(changeCurrentIndexAndSongAction(1))
        }
    }

    return (
        <PlaybarWrapper className="sprite_playbar">
            <div className="content wrap-v2">
                <Control isPlaying={isPlaying}>
                    <button className="sprite_playbar prev" onClick={e => changeMusic(-1)}></button>
                    <button className="sprite_playbar play" onClick={e => playMusic()}></button>
                    <button className="sprite_playbar next" onClick={e => changeMusic(1)}></button>
                </Control>
                <PlayInfo>
                    <div className="image">
                        <NavLink to="/discover/player">
                            <img src={getSizeImage(picUrl, 35)} alt="" />
                        </NavLink>
                    </div>
                    <div className="info">
                        <div className="song">
                            <span className="song-name">{currentSong.name}</span>
                            <a className="singer-name" href="/todo">{singerName}</a>
                        </div>
                        <div className="progress">
                            <Slider defaultValue={0} 
                                    value={progess} 
                                    tooltipVisible={false}
                                    onChange={slideChange}
                                    onAfterChange={slideAfterChange}/>
                            <div className="time">
                                <span className="now-time">{showCurrentTime}</span>
                                <span className="divider">/</span>
                                <span className="duration">{showDuration}</span>
                            </div>
                        </div>
                    </div>
                </PlayInfo>
                <Operator sequence={sequence}>
                    <div className="left">
                        <button className="sprite_playbar btn favor"></button>
                        <button className="sprite_playbar btn share"></button>
                    </div>
                    <div className="right sprite_playbar">
                        <button className="sprite_playbar btn volume"></button>
                        <button className="sprite_playbar btn loop" onClick={e => changeSequence()}></button>
                        <button className="sprite_playbar btn playlist">{playList.length}</button>
                    </div>
                </Operator>
            </div>
            <audio ref={audioRef} 
                    onTimeUpdate={e => timeUpdate(e)} 
                    onEnded={e => handleMusicEnded()}/>
        </PlaybarWrapper>
    )
})
